package com.itmck.control;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.itmck.dto.response.ApiResultResponse;
import com.itmck.handler.SentinelHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * 太阳当空照,花儿对我笑
 * <p>
 * Create by M ChangKe 2021/11/2 20:50
 **/
@Slf4j
@RestController
public class OrderSentinelController {


    //=================================结合控制台进行限流================================================

    //这里不用使用 @SentinelResource,也能被识别,会走自定义sentinel全局异常处理器
    @GetMapping("/order/sentinel/getOrder")
    public ApiResultResponse<String> getOrder(@RequestParam String name) {
        log.info("模拟sentinel进行接口流控,入参:{}", name);
        return ApiResultResponse.ok(name);
    }


    @SentinelResource(
            value = "/order/sentinel/getOrder2",
            blockHandler = "blockHandlerFunc",
            fallback = "fallbackFunc",
            blockHandlerClass = SentinelHandler.class,
            fallbackClass = SentinelHandler.class
    )
    @GetMapping("/order/sentinel/getOrder2")
    public ApiResultResponse<String> getOrder2(@RequestParam String name) {
        log.info("模拟sentinel进行接口流控,入参:{}", name);
        return ApiResultResponse.ok(name);
    }


    //===================================代码自定义限流规则=====================================================
    @GetMapping("/order/sentinel/getOrder3")
    public ApiResultResponse<String> getOrder3(@RequestParam String name) {
        log.info("模拟sentinel进行接口流控,入参:{}", name);
        return ApiResultResponse.ok(name);
    }


    /**
     * 代码中设置限流规则
     */
    @PostConstruct
    private void initFlowQpsRule() {
        // 规则列表
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule("/order/sentinel/getOrder2");
        // 针对来源
        rule.setLimitApp("default");
        // 设置阈值类型为QPS
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 单机阈值
        rule.setCount(2);
        // 将规则添加到规则列表
        rules.add(rule);
        // 加载规则列表
        FlowRuleManager.loadRules(rules);
    }


}